
#include "Impl_Engine.h"
#include "Impl_Component.h"
#include "Impl_Scene.h"

#include <Engine/Render.h>

_BeginNamespace(Radix)

Engine::Engine()
	:mComponentSystem(nullptr),

	mRenderSystem(nullptr),
	mAudioSystem(nullptr),
	mInputSystem(nullptr),
	mPhysxSystem(nullptr),

	mSceneSystem(nullptr),

	mLogger()
{}

Engine::~Engine()
{}

bool Engine::init(const StringValueMap& params)
{
	StringValueMap configs = params;

	String logHome = configs[_T("LogHome")];
	Logger::Level logLev = (Logger::Level)(int)(configs[_T("LogLevel")]);
	String logName = _T("Engine.log");
	if(! mLogger.open(logHome+logName, logLev))
		return false;
	
	mLogger.logMessage(Logger::eLevel_Info, 
		_T("ComponentSystem initializing."));
	mComponentSystem = new ComponentSystem();
	StringVector moduleNames = StringUtil::split(configs[_T("ComponentModules")], _T(";"));
	auto nameIter = moduleNames.begin();
	while(nameIter != moduleNames.end())
	{
		if(! mComponentSystem->loadModule(*nameIter))
		{
			mLogger.logMessage(Logger::eLevel_Warning, 
				_T("ComponentModule [%s] load faild."), nameIter->c_str());
		}
		++ nameIter;
	}

	mLogger.logMessage(Logger::eLevel_Info, 
		_T("RenderSystem initializing."));
	mRenderSystem = dynamic_cast<IRenderSystem*>(mComponentSystem->selectComponent(configs[_T("RenderSystem")]));
	if(mRenderSystem == nullptr)
	{
		mLogger.logMessage(Logger::eLevel_Error, 
			_T("RenderSystem [%s] not found."), configs[_T("RenderSystem")].string().c_str());
		return false;
	}
	if(! mRenderSystem->init(params))
	{
		mLogger.logMessage(Logger::eLevel_Error, 
			_T("RenderSystem [%s] init failed."), configs[_T("RenderSystem")].string().c_str());
		return false;
	}

	//mSceneSystem = new SceneSystem();

	return true;
}

void Engine::exit()
{
	if(mRenderSystem != nullptr)
	{
		mRenderSystem->exit();
		mLogger.logMessage(Logger::eLevel_Info, 
			_T("RenderSystem exited."));
	}

	if(mComponentSystem != nullptr)
	{
		delete mComponentSystem;
		mComponentSystem = nullptr;
		mLogger.logMessage(Logger::eLevel_Info, 
			_T("ComponentSystem destroyed."));
	}

	mLogger.close();
}

void Engine::update(real elapsed)
{
	mRenderSystem->renderFrame(elapsed);
}

ISceneSystem* Engine::sceneSystem()
{
	return mSceneSystem;
}

extern "C"
{
	_RadixApi void CreateEngine(IEngine** engine)
	{
		*engine = new Engine();
	}

	_RadixApi void DeleteEngine(IEngine** engine)
	{
		if(*engine != nullptr)
		{
			delete *engine;
			*engine = nullptr;
		}
	}
}

_EndNamespace(Radix)
